#include "halldevice.h"
#include <QApplication>
extern QByteArray  globalSendData;
HallDevice::HallDevice(QObject *parent) : QObject(parent)
{
    this->moveToThread(&mthread);
    mthread.start();
    connect(this,SIGNAL(ToCreateDevice()),this,SLOT(Slot_CreateDevice()),Qt::BlockingQueuedConnection);
    emit ToCreateDevice();
    SlotInit();
}

HallDevice::~HallDevice()
{
    mthread.quit();
    mthread.wait();
}

void HallDevice::OpenDevice()
{
    emit ToOpenDevice();
}

void HallDevice::CloseDevice()
{
    emit ToCloseDevice();
}

void HallDevice::SlotInit()
{
    connect(this,SIGNAL(ToOpenDevice()),SLOT(Slot_OpenDevcie()));
    connect(this,SIGNAL(ToCloseDevice()),SLOT(Slot_CloseDevice()));
    connect(this,SIGNAL( ToSendData(QByteArray,int)),this,SLOT(Slot_SendData(QByteArray,int)));
}

void HallDevice::SendData(QByteArray sendData, int recvLength)
{
    emit ToSendData(sendData,recvLength);
}

void HallDevice::Slot_CreateDevice()
{
    serialCoreObject=new SerialCore();
    qDebug()<<"[HallDevice]:Create Device Success";
}

void HallDevice::Slot_OpenDevcie()
{
    serialCoreObject->Open();
    if(serialCoreObject->mPort.isOpen())
    {
        qDebug()<<"[HallDevice]:open port success";
        QString tmp;
        tmp="打开"+serialCoreObject->mPort.portName()+"成功";
        emit ToShowMessageBox(tmp);
    }
    else
    {
        qDebug()<<"[HallDevice]:open port faliled";
        QString tmp;
        tmp="打开"+serialCoreObject->mPort.portName()+"失败";
        emit ToShowMessageBox(tmp);
    }
}

void HallDevice::Slot_CloseDevice()
{
    serialCoreObject->Close();
    if(serialCoreObject->mPort.isOpen())
    {
        QString tmp;
        tmp="关闭"+serialCoreObject->mPort.portName()+"失败";
        emit ToShowMessageBox(tmp);
    }
    else
    {
        QString tmp;
        tmp="关闭"+serialCoreObject->mPort.portName()+"成功";
        emit ToShowMessageBox(tmp);
    }
}

void HallDevice::Slot_SendData(QByteArray sendData, int recvLength)
{
    QByteArray readData;
    readData.clear();
    serialCoreObject->Write(sendData);
    emit ToShowSendRecv("send:"+sendData.toHex());
    serialCoreObject->Read(recvLength,readData);
    emit ToShowSendRecv("recv:"+readData.toHex());

    recvBuf=readData;
    hasRecv=true;
}

QByteArray HallDevice::RecvProgrammingDeviceData()
{
    while (!hasRecv)
    {
        QApplication::processEvents();
    }
    return recvBuf;
}

ReadRegisterValue HallDevice::ReadSingleRegister(unsigned char registerAddress)
{

    hasRecv=false;

    //初始化返回值
    ReadRegisterValue ret;
    ret.success=false;
    ret.value=0;

    //形成数据帧
    QString tmpStr="E106F0";

    QByteArray sendArray;
    sendArray.clear();

    sendArray.append(QByteArray::fromHex(tmpStr.toUtf8()));
    sendArray.append(registerAddress);
    sendArray.append(1);

    unsigned char crc=CRC8((unsigned char *)sendArray.data(),sendArray.length());

    sendArray.append(crc);

    //发送
    SendData(sendArray,8);
    globalSendData=sendArray;
    //emit ToShowSendRecv("Send:"+sendArray.toHex());
    //接收
    QByteArray recvArray=RecvProgrammingDeviceData();
    //emit ToShowSendRecv("Recv:"+recvArray.toHex());

    //判断CRC
    if(recvArray.length()>=6)
    {
        if((uchar)CRC8((unsigned char*)recvArray.data(),5)==(uchar)recvArray[5])
        {
        }
        else
        {
            ret.success=false;
            return ret;
        }
    }
    else
        ret.success=false;

    if(recvArray.length()>=5&&(uchar)recvArray[0]==0xe1&&(uchar)recvArray[1]==0x05&&(uchar)recvArray[3]==0xff)
    {
        ret.success=false;
        return  ret;
    }


    ret.success=true;
    ret.value=recvArray.data()[4];

    qDebug()<<"send:"<<sendArray.toHex();
    qDebug()<<"recv:"<<recvArray.toHex();

    return ret;
}

bool HallDevice::WriteSingleRegister(uchar adress, uchar value)
{
    hasRecv=false;
    bool ret=false;
    //形成数据帧
    QString tmpStr="E107F1";
    QByteArray sendArray;
    sendArray.clear();
    sendArray.append(QByteArray::fromHex(tmpStr.toUtf8()));
    sendArray.append(adress);
    sendArray.append(1);
    sendArray.append(value);
    unsigned char crc=CRC8((unsigned char *)sendArray.data(),sendArray.length());
    sendArray.append(crc);
    //发送
    SendData(sendArray,8);
   // emit ToShowSendRecv("Send:"+sendArray.toHex());
    qDebug()<<"写寄存器发送数据："<<sendArray.toHex();
    //接收
    QByteArray recvArray=RecvProgrammingDeviceData();
    //emit ToShowSendRecv("Recv:"+recvArray.toHex());

    qDebug()<<"写寄存器返回数据："<<recvArray.toHex();

    //判断crc
    if(recvArray.length()>1)
    {
        if((uchar)CRC8((unsigned char*)recvArray.data(),recvArray.length()-1)==(uchar)recvArray[recvArray.length()-1])
        {

        }
        else
        {
            return  false;
        }
    }
    //判断数据
    if((uchar)recvArray.data()[0]==0xe1&&(uchar)recvArray.data()[1]==0x06&&(uchar)recvArray.data()[2]==0xf1&&(uchar)recvArray.data()[3]==adress&&(uchar)recvArray.data()[4]==value)
    {
        ret=true;
        return  ret;
    }

    return ret;
}

bool HallDevice::HallChipControl(unsigned char type)
{

    hasRecv=false;
    //形成数据帧
    QString tmpStr="E105F2";
    QByteArray sendArray;
    sendArray.clear();
    sendArray.append(QByteArray::fromHex(tmpStr.toUtf8()));

    uchar controlType=type;
    sendArray.append(controlType);

    uchar crc=CRC8((unsigned char *)sendArray.data(),sendArray.length());

    sendArray.append(crc);

    //发送
    SendData(sendArray,8);

    //接收
    QByteArray recvArray=RecvProgrammingDeviceData();

    sendArray.append((char)0);
    sendArray.append((char)0);
    sendArray.append((char)0);
    //判断CRC
    if(recvArray.length()>1)
    {
        if((uchar)CRC8((unsigned char*)recvArray.data(),recvArray.length()-1)==(uchar)recvArray[recvArray.length()-1])
        {
            //qDebug()<<"Crc is OK";
        }
        else
        {
            return  false;
        }
    }
    //判断编程器与霍尔通信异常
    if(recvArray.length()>=5&&(uchar)recvArray[0]==0xe1&&(uchar)recvArray[1]==0x05&&(uchar)recvArray[3]==0xff)
    {
        return  false;
    }

    //判断
    if(recvArray.compare(sendArray)==0)
    {
        qDebug()<<"recv:"<<recvArray.toHex();
        qDebug()<<"send:"<<sendArray.toHex();
        return true;
    }
    return false;
}

bool HallDevice::ChannelSwitch(unsigned char channel)
{
    hasRecv=false;

    QString tmpStr="E105F5";
    QByteArray sendArray;
    sendArray.clear();
    sendArray.append(QByteArray::fromHex(tmpStr.toUtf8()));

    sendArray.append(channel);

    uchar crc=CRC8((unsigned char *)sendArray.data(),sendArray.length());

    sendArray.append(crc);

    SendData(sendArray,8);
    //emit ToShowSendRecv("Send:"+sendArray.toHex());

    QByteArray recvArray=RecvProgrammingDeviceData();
    recvArray.remove(0,recvArray.indexOf(0xe1));
    //emit ToShowSendRecv("Recv:"+recvArray.toHex());


    sendArray.append((char)0);
    sendArray.append((char)0);
    sendArray.append((char)0);

    //判断CRC
    if(recvArray.length()>1)
    {
        if((uchar)CRC8((unsigned char*)recvArray.data(),recvArray.length()-1)==(uchar)recvArray[recvArray.length()-1])
        {
            //qDebug()<<"Crc is OK";
        }
        else
        {
            return  false;
        }
    }
    //判断编程器与霍尔通信异常
    if(recvArray.length()>=5&&(uchar)recvArray[0]==0xe1&&(uchar)recvArray[1]==0x05&&(uchar)recvArray[3]==0xff)
    {
        return  false;
    }

    //判断
    if(recvArray.compare(sendArray)==0)
    {
        qDebug()<<"切换通道send:"<<sendArray.toHex();
        qDebug()<<"切换通道recv:"<<recvArray.toHex();
        return true;
    }
    return false;
}

bool HallDevice::SwitchToMeasureVoltageMode()
{
    QThread::msleep(50);
    bool ret=this->WriteSingleRegister(0x21,96);
    if(!ret)
    {
        return  ret;
    }
    QThread::msleep(50);
    ret=this->WriteSingleRegister(0x22,0);
    if(!ret)
    {
        return ret;
    }


    QThread::msleep(50);
    ret=this->WriteSingleRegister(0x20,1);
    return  ret;
}

void HallDevice::Aotu_LoadParam(float TempData, QString Mod)
{
    if(Mod == "基础零点")
    {
        Zero_BasicsOutV = TempData;
        //ui->lineEdit_ZeroOut->setText(QString("%1").arg(Zero_BasicsOutV));
    }
    else if(Mod == "基础满值")
    {
        Full_BasicsOutV = TempData;
        //ui->lineEdit_UnOut->setText(QString("%1").arg(Full_BasicsOutV));
    }
    else if(Mod == "调试零点")
    {
        if(IsGetZeroLSB)
        {
            IsGetZeroLSB = false;
            ZeroVChange = Calib_ZeroOutV - TempData;
            ZeroLSB_Value = abs(ZeroVChange/ZeroWriteChange);
        }
        Calib_ZeroOutV = TempData;
    }
    else    //调试满值
    {
        Calib_FullOutV = TempData;
    }
}

bool HallDevice::SingleRegisterBurn(uchar address, uchar registerValue)
{
    hasRecv=false;
    //形成数据帧
    QString tmpStr="E107F3";
    QByteArray sendArray;
    sendArray.clear();
    sendArray.append(QByteArray::fromHex(tmpStr.toUtf8()));
    sendArray.append(address);
    sendArray.append(1);
    sendArray.append(registerValue);

    uchar crc=CRC8((unsigned char*)sendArray.data(),sendArray.length());
    sendArray.append(crc);

    SendData(sendArray,8);

    QByteArray recvArray=RecvProgrammingDeviceData();


    if(recvArray.length()>1)
    {
        if((uchar)CRC8((unsigned char*)recvArray.data(),recvArray.length()-1)==(uchar)recvArray[recvArray.length()-1])
        {
            //qDebug()<<"Crc is OK";
        }
        else
        {
            return  false;
        }
    }

    //判断编程器与霍尔通信异常
    if(recvArray.length()>=5&&(uchar)recvArray[0]==0xe1&&(uchar)recvArray[1]==0x05&&(uchar)recvArray[3]==0xff)
    {
        return  false;
    }

    if(recvArray.length()>=6)
    {
        if((uchar)recvArray.data()[0]!=0xe1)
        {
            return false;
        }

        if((uchar)recvArray.data()[1]!=0x06)
        {
            return false;
        }

        if((uchar)recvArray.data()[2]!=0xf3)
        {
            return false;
        }

        if((uchar)recvArray.data()[3]!=address)
        {
            return false;
        }

        if((uchar)recvArray.data()[4]!=registerValue)
        {
            return false;
        }
    }
    else
        return  false;

    return  true;
}

bool HallDevice::AllRegisterBurn()
{
    hasRecv=false;
    QString tmpStr="E107F412016A";
    QByteArray sendArray;
    sendArray.clear();
    sendArray.append(QByteArray::fromHex(tmpStr.toUtf8()));

    uchar crc=CRC8((uchar*)sendArray.data(),sendArray.length());
    sendArray.append(crc);

    SendData(sendArray,8);

    QByteArray recvArray=RecvProgrammingDeviceData();

    sendArray.append((uchar)0);

    if(sendArray.compare(recvArray)==0)
    {
        return  true;
    }
    else
        return false;
}

uchar HallDevice::CRC8(uchar *Buf, int len)
{
    uchar crc = 0x00;
    uchar bit;

    while(len--)
    {
        crc ^= *Buf++;  // 异或操作
        for( bit = 0; bit<8; bit++ )
        {
            if (crc & 0x80)  // 最高位为1
            {
                crc = (crc << 1) ^ 0x07;  // 与0x07进行异或和左移操作
            }
            else
            {
                crc <<= 1;  // 左移操作
            }
        }
    }
    return crc;
}
void HallDevice::ZeroCalibration(float DifferenceValue)
{
    uint16_t TempData;
    float TempZeroGain;
    TempZeroGain = (DifferenceValue/ZeroLSB_Value)/16383.0 + ZeroDAC;
    if((TempZeroGain < 0) || (TempZeroGain > 1))
    {
        //CreateMessage("零点计算溢出！");
        return;
    }
    TempData = TempZeroGain*16383;
    ZeroDAC = TempZeroGain;
    GS302_ZeroDAC = ZeroDAC;

    GS302_K0H = TempData>>8;
    GS302_K0L = TempData&0xFF;
    //ui->label_FloatZero->setText(QString("%1").arg(ZeroDAC));
}
